/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import me.zhengjie.modules.biz.domain.*;
import me.zhengjie.modules.biz.repository.*;
import me.zhengjie.modules.biz.service.dto.*;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.modules.system.repository.UserRepository;
import me.zhengjie.utils.ValidationUtil;
import me.zhengjie.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import me.zhengjie.modules.biz.service.OpendoorrecordService;
import me.zhengjie.modules.biz.service.mapstruct.OpendoorrecordMapper;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.io.IOException;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author Admin
* @date 2023-04-17
**/
@Service
@RequiredArgsConstructor
public class OpendoorrecordServiceImpl implements OpendoorrecordService {

    private final OpendoorrecordRepository opendoorrecordRepository;
    private final OpendoorrecordMapper opendoorrecordMapper;
    private final UserRepository userRepository;
    private final LabRepository labRepository;

    @Override
    public Map<String,Object> queryAll(OpendoorrecordQueryCriteria criteria, Pageable pageable){
        Specification<Opendoorrecord> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (criteria.getUserName() != null) {
                predicates.add(criteriaBuilder.like(root.get("userName"), "%" + criteria.getUserName() + "%"));
            }
            if (criteria.getLabId() != null) {
                predicates.add(criteriaBuilder.equal(root.get("labId"), criteria.getLabId()));
            }
            if (criteria.getType() != null) {
                predicates.add(criteriaBuilder.equal(root.get("type"), criteria.getType()));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        Page<Opendoorrecord> page = opendoorrecordRepository.findAll(specification ,pageable);
        Page<OpendoorrecordDto> dto = page.map(opendoorrecordMapper::toDto);
        List<OpendoorrecordDto> resultDto = dto.getContent();
        for (OpendoorrecordDto opendoorrecordDto:resultDto) {
            if (opendoorrecordDto.getUserId() != null) {
                User user = userRepository.findById(Long.valueOf(opendoorrecordDto.getUserId())).orElseGet(User::new);
                opendoorrecordDto.setUserName(user.getUsername());
            }
            if (opendoorrecordDto.getLabId() != null) {
                Lab lab = labRepository.findById(opendoorrecordDto.getLabId()).orElseGet(Lab::new);
                opendoorrecordDto.setLabName(lab.getName());
            }
        }
        return PageUtil.toPage(dto);
    }

    @Override
    public List<OpendoorrecordDto> queryAll(OpendoorrecordQueryCriteria criteria){
        Specification<Opendoorrecord> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (criteria.getUserName() != null) {
                predicates.add(criteriaBuilder.like(root.get("userName"), "%" + criteria.getUserName() + "%"));
            }
            if (criteria.getLabId() != null) {
                predicates.add(criteriaBuilder.equal(root.get("labId"), criteria.getLabId()));
            }
            if (criteria.getType() != null) {
                predicates.add(criteriaBuilder.equal(root.get("type"), criteria.getType()));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        List<Opendoorrecord> opendoorrecordList = opendoorrecordRepository.findAll(specification);
        List<OpendoorrecordDto> opendoorrecordDtoList = opendoorrecordMapper.toDto(opendoorrecordList);
        for (OpendoorrecordDto opendoorrecordDto : opendoorrecordDtoList) {
            if (opendoorrecordDto.getUserId() != null) {
                User user = userRepository.findById(Long.valueOf(opendoorrecordDto.getUserId())).orElseGet(User::new);
                opendoorrecordDto.setUserName(user.getUsername());
            }
            if (opendoorrecordDto.getLabId() != null) {
                Lab lab = labRepository.findById(opendoorrecordDto.getLabId()).orElseGet(Lab::new);
                opendoorrecordDto.setLabName(lab.getName());
            }
        }
        return opendoorrecordDtoList;
    }

    @Override
    @Transactional
    public OpendoorrecordDto findById(Integer id) {
        Opendoorrecord opendoorrecord = opendoorrecordRepository.findById(id).orElseGet(Opendoorrecord::new);
        ValidationUtil.isNull(opendoorrecord.getId(),"Opendoorrecord","id",id);
        return opendoorrecordMapper.toDto(opendoorrecord);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OpendoorrecordDto create(Opendoorrecord resources) {
        return opendoorrecordMapper.toDto(opendoorrecordRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Opendoorrecord resources) {
        Opendoorrecord opendoorrecord = opendoorrecordRepository.findById(resources.getId()).orElseGet(Opendoorrecord::new);
        ValidationUtil.isNull( opendoorrecord.getId(),"Opendoorrecord","id",resources.getId());
        opendoorrecord.copy(resources);
        opendoorrecordRepository.save(opendoorrecord);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            opendoorrecordRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<OpendoorrecordDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (OpendoorrecordDto opendoorrecord : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("操作人",  opendoorrecord.getUserName());
            map.put("时间",  opendoorrecord.getCreatedAt());
            String record = "";
            map.put("开/关门记录",  record);
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public Object getList(HttpServletRequest request) {
//        ///api/acs/v2/door/events
        RestTemplate restTemplate = new RestTemplate();
        try {
            HttpHeaders headers = new HttpHeaders();
            String url = "https:/api/acs/v2/door/events";
            JSONObject postData = new JSONObject();
            postData.put("pageNo", request.getParameter("page"));
            postData.put("pageSize", request.getParameter("size"));
            if (request.getParameter("doorIndexCodes")!=null){
                postData.put("doorIndexCodes", request.getParameter("doorIndexCodes"));
            }
            if (request.getParameter("doorName")!=null){
                postData.put("doorName", request.getParameter("doorName"));
            }
            if (request.getParameter("startTime")!=null){
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                LocalDateTime dateTimeStart = LocalDateTime.parse(request.getParameter("startTime"), formatter);
                LocalDateTime dateTimeEnd = LocalDateTime.parse(request.getParameter("endTime"),formatter);
                formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
                String startTime = formatter.format(dateTimeStart);
                String endTime = formatter.format(dateTimeEnd);
                postData.put("startTime", startTime);
                postData.put("endTime",endTime);
            }
            if (request.getParameter("personName")!=null){
                postData.put("personName", request.getParameter("personName"));
            }
            String jsonString = JSONObject.toJSONString(postData);
            HttpEntity<String> entity = new HttpEntity<>(jsonString, headers);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, entity, String.class);

            return responseEntity.getBody();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Object getPicture(String svrIndexCode, String picUri) {
        ///api/acs/v1/event/pictures
        RestTemplate restTemplate = new RestTemplate();
        try {

            HttpHeaders headers = new HttpHeaders();
            String url = "https:/api/acs/v1/event/pictures";
            JSONObject postData = new JSONObject();
            postData.put("svrIndexCode", svrIndexCode);
            postData.put("picUri", picUri);
            String jsonString = JSONObject.toJSONString(postData);
            HttpEntity<String> entity = new HttpEntity<>(jsonString, headers);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, entity, String.class);

            return responseEntity.getBody();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }
}
